/**
 * Camera Class
 * 
 * Manages the camera view for the scene.
 */
export class Camera {
  private x: number;
  private y: number;
  private scale: number;
  private rotation: number;
  private width: number;
  private height: number;

  /**
   * Creates an instance of Camera.
   * @param width - Width of the camera viewport
   * @param height - Height of the camera viewport
   */
  constructor(width: number = 800, height: number = 600) {
    this.x = 0;
    this.y = 0;
    this.scale = 1;
    this.rotation = 0;
    this.width = width;
    this.height = height;
  }

  /**
   * Gets the camera x position
   * @returns number - The x position
   */
  public getX(): number {
    return this.x;
  }

  /**
   * Sets the camera x position
   * @param x - The new x position
   */
  public setX(x: number): void {
    this.x = x;
  }

  /**
   * Gets the camera y position
   * @returns number - The y position
   */
  public getY(): number {
    return this.y;
  }

  /**
   * Sets the camera y position
   * @param y - The new y position
   */
  public setY(y: number): void {
    this.y = y;
  }

  /**
   * Gets the camera scale
   * @returns number - The scale factor
   */
  public getScale(): number {
    return this.scale;
  }

  /**
   * Sets the camera scale
   * @param scale - The new scale factor
   */
  public setScale(scale: number): void {
    this.scale = scale;
  }

  /**
   * Gets the camera rotation
   * @returns number - The rotation in degrees
   */
  public getRotation(): number {
    return this.rotation;
  }

  /**
   * Sets the camera rotation
   * @param rotation - The new rotation in degrees
   */
  public setRotation(rotation: number): void {
    this.rotation = rotation;
  }

  /**
   * Gets the camera width
   * @returns number - The width
   */
  public getWidth(): number {
    return this.width;
  }

  /**
   * Sets the camera width
   * @param width - The new width
   */
  public setWidth(width: number): void {
    this.width = width;
  }

  /**
   * Gets the camera height
   * @returns number - The height
   */
  public getHeight(): number {
    return this.height;
  }

  /**
   * Sets the camera height
   * @param height - The new height
   */
  public setHeight(height: number): void {
    this.height = height;
  }

  /**
   * Moves the camera by a relative amount
   * @param dx - Change in x position
   * @param dy - Change in y position
   */
  public move(dx: number, dy: number): void {
    this.x += dx;
    this.y += dy;
  }

  /**
   * Zooms the camera by a relative amount
   * @param ds - Change in scale factor
   */
  public zoom(ds: number): void {
    this.scale *= ds;
  }

  /**
   * Rotates the camera by a relative amount
   * @param dr - Change in rotation in degrees
   */
  public rotate(dr: number): void {
    this.rotation += dr;
  }

  /**
   * Transforms the canvas context based on camera properties
   * @param context - The canvas context to transform
   */
  public transformContext(context: any): void {
    if (!context) {
      return;
    }

    // Apply camera transformations in order:
    // 1. Translate to camera position
    // 2. Rotate around center
    // 3. Scale
    // 4. Translate back
    
    const centerX = this.width / 2;
    const centerY = this.height / 2;
    
    context.translate(centerX, centerY);
    context.scale(this.scale, this.scale);
    context.rotate(this.rotation * Math.PI / 180);
    context.translate(-centerX - this.x, -centerY - this.y);
  }

  /**
   * Gets the camera viewport
   * @returns any - The viewport rectangle
   */
  public getViewport(): any {
    // Calculate actual viewport based on camera properties and canvas size
    const viewportWidth = this.width / this.scale;
    const viewportHeight = this.height / this.scale;
    
    return {
      x: this.x - viewportWidth / 2,
      y: this.y - viewportHeight / 2,
      width: viewportWidth,
      height: viewportHeight
    };
  }
}